
using namespace std;

#include "RunEval.h"

void storex_testing::getFileName(string &result, string &name, int mode) {
	result+="Results/";
	result+=name;
	string type;
	if (mode==1) type = "_detection";
	else if (mode==2) type = "_dropped";
	else type = "_time";
	result+=type;
}

void storex_testing::getDetectionFile(string &result, string &name) {
	getFileName(result, name, 1);
}

void storex_testing::getDroppedFile(string &result, string &name) {
	getFileName(result, name, 2);
}

void storex_testing::getProcTimeFile(string &result, string &name) {
	getFileName(result, name, 3);
}

void storex_testing::runEval() {


	// What to run?
	bool simple = true;
	bool complex = false;

	bool runTableTestSlot = true;
	bool runTestWindow = false;
	bool runTestLast = false;
	bool runTestWindowExp = false;
	bool runTestWindowSize = true;
	bool runTestType = false;
	bool runTestSlotExtended = false;
	bool runEachLastRuleTest = false;
/*
	bool runPriorityTableTestThresold = false;
	bool runStorageOCMTestNumTypes = false;
	bool runTableTestWindow = false;
*/


// *************************************************************************************************************************************************************************** //
// ************************************************************************** SIMPLE ***************************************************************************************** //
// *************************************************************************************************************************************************************************** //


if (simple){

// ------------- Run table test (per slot) [detection + time] --------------- //

	if (runTableTestSlot) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);
		paramHandler->setParLastProb(0.4);
		/***  ***/

		for (int seed=0; seed<1; seed++){

			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, false);
			queue<PubPkt*> tempPubQueue;
			queue<BackSubPkt*> tempSubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}
			for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createBackSubPkt();
				tempSubQueue.push(pkt);
			}

		// **** DATABASE *** //
			/*
			string nameDB = "sToRex_Simple_TableTestSlot_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Simple_TableTestSlot_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}


			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));

			}
*/
/*
		// **** CACHE *** //

			string nameCache = "sToRex_Simple_TableTestSlot_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Simple_TableTestSlot_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(CACHE);
			//configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}
*/

		// **** DISK *** //

			string nameDisk = "sToRex_TableTestSlot_Disk";
			stringstream streamDisk;
			string detectionFileDisk;
			getDetectionFile(detectionFileDisk, nameDisk);

			string nameDisk2 = "sToRex_TableTestSlot_Disk";
			string timesFileDisk;
			getProcTimeFile(timesFileDisk, nameDisk2);
/*
			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

			}
*/
/*
			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}
*/
			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(500);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}


/*
			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			while (tempSubQueue.size() != 0){
				BackSubPkt* pkt = tempSubQueue.front();
				tempSubQueue.pop();
				delete pkt;
			}
*/
		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;

	}



// ----------------------------------------------------------------- Run test window [detection + time] ------------------------------------------------------------ //

	if (runTestWindow) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(UNIFORM);
		paramHandler->setParLastProb(0.4);
		/***  ***/

		for (int seed=0; seed<1; seed++){
			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, false);
			queue<PubPkt*> tempPubQueue;
			//queue<BackSubPkt*> tempSubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setParWindowDistribution(sigma);
				Producer *p = new Producer(paramHandler, false);
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
				}
				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(sigma, innerSubQueue));
			}

	/*		for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createBackSubPkt();
				tempSubQueue.push(pkt);
			}
	*/
		// **** DATABASE *** //

			string nameDB = "sToRex_Simple_WindowTest_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Simple_WindowTest_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);


			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/

				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner* runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
				cout << "ciaoEXIT!" << endl;
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setNumSlot(50);

			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;

				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			configHandler->setMemoryTableType(ALLOCATION);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}


		// **** CACHE *** //

			string nameCache = "sToRex_Simple_WindowTest_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Simple_WindowTest_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			//configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner =  new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

/*
		// **** DISK *** //

			string nameDisk = "sToRex_TableTestSlot_Disk";
			stringstream streamDisk;
			string detectionFileDisk;
			getDetectionFile(detectionFileDisk, nameDisk);

			string nameDisk2 = "sToRex_TableTestSlot_Disk";
			string timesFileDisk;
			getProcTimeFile(timesFileDisk, nameDisk2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(DISK);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}
*/

			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
				while (it->second.size() != 0){
					BackSubPkt* pkt = it->second.front();
					it->second.pop();
					delete pkt;
				}
			}

		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;

	}



	// ----------------------------------------------------------------- Run test Last [detection + time] ------------------------------------------------------------ //

		if (runTestLast) {
			ParamHandler *paramHandler = new ParamHandler();
			ConfigHandler *configHandler = new ConfigHandler();
			OutputListener *outputListener = new EvalOutputListener();

			/*** parametri del test ***/
			paramHandler->setNumEventTypes(10);
			paramHandler->setNumNames(1000);
			paramHandler->setNumStringValues(200);
			paramHandler->setMaxNumAttributes(4);
			paramHandler->setMinNumAttributes(1);
			paramHandler->setMaxIntValue(1000);
			paramHandler->setMinIntValue(5);
			paramHandler->setPubNum (10000);
			paramHandler->setSubNum(400);
			paramHandler->setNumInterfaces(8);
			paramHandler->setMaxWindowSize(300*1000); // Milliseconds
			paramHandler->setPercIntEq(20);
			paramHandler->setPercIntGt(40);
			paramHandler->setPercIntLt(40);
			paramHandler->setEventInputDistribution(NORMAL);
			paramHandler->setSubsInputDistribution(NORMAL);
			paramHandler->setWindowSizeDistribution(NORMAL);
			paramHandler->setParWindowDistribution(1);
			/***  ***/

			for (int seed=9; seed<10; seed++){
				srand(seed);
				paramHandler->setSeed(seed);
				Producer *p = new Producer(paramHandler, false);
				queue<PubPkt*> tempPubQueue;
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
					tempPubQueue.push(pkt);
				}

				map<float, queue<BackSubPkt*> > tempSubsMap;
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
					paramHandler->setSeed(seed);
					paramHandler->setParLastProb(probLast);
					Producer *p = new Producer(paramHandler, false);
					queue<BackSubPkt*> innerSubQueue;
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						innerSubQueue.push(pkt);
					}
					tempSubsMap.insert(make_pair(probLast, innerSubQueue));
				}

			// **** DATABASE *** //

				string nameDB = "sToRex_Simple_LastTest_Database";
				stringstream streamDB;
				string detectionFileDB;
				getDetectionFile(detectionFileDB, nameDB);

				string nameDB2 = "sToRex_Simple_LastTest_Database";
				string timesFileDB;
				getProcTimeFile(timesFileDB, nameDB2);

				//Oracolo
				configHandler->setDefaultOracle();
				configHandler->setStorageType(DATABASE);

				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;

	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/

					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/
				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setNumSlot(100);

				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;

					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;

	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}

				//allocationTable
				configHandler->setDefaultSienaFF();
				configHandler->setMemoryTableType(ALLOCATION);
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;

	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "AllocationTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}


			// **** CACHE *** //

				string nameCache = "sToRex_Simple_LastTest_Cache";
				stringstream streamCache;
				string detectionFileCache;
				getDetectionFile(detectionFileCache, nameCache);

				string nameCache2 = "sToRex_Simple_LastTest_Cache";
				string timesFileCache;
				getProcTimeFile(timesFileCache, nameCache2);

				//Oracolo
				configHandler->setDefaultOracle();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				//configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/
				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}


				//allocationTable
				configHandler->setDefaultSienaFF();
				configHandler->setMemoryTableType(ALLOCATION);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(100);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
	/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						subQueue.push(pkt);
					}
	*/				int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "AllocationTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
	/*
					while (subQueue.size() != 0){
						BackSubPkt* pkt = subQueue.front();
						subQueue.pop();
						delete pkt;
					}
	*/			}

/*
			// **** DISK *** //

				string nameDisk = "sToRex_TableTestSlot_Disk";
				stringstream streamDisk;
				string detectionFileDisk;
				getDetectionFile(detectionFileDisk, nameDisk);

				string nameDisk2 = "sToRex_TableTestSlot_Disk";
				string timesFileDisk;
				getProcTimeFile(timesFileDisk, nameDisk2);

				//Oracolo
				configHandler->setDefaultOracle();
				//configHandler->setStorageType(DISK);
				for (int i=10; i<=10; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setStorageType(DISK);
				for (int i=10; i<=100; i=i+10){
					srand(0);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setStorageType(DISK);
				for (int i=10; i<=100; i=i+10){
					srand(0);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setStorageType(DISK);
				configHandler->setSubsThreshold(150);
				for (int i=10; i<=100; i=i+10){
					srand(0);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}
	*/

				while (tempPubQueue.size() != 0){
					PubPkt* pkt = tempPubQueue.front();
					tempPubQueue.pop();
					delete pkt;
				}

				for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
					while (it->second.size() != 0){
						BackSubPkt* pkt = it->second.front();
						it->second.pop();
						delete pkt;
					}
				}

			}

			delete outputListener;
			delete configHandler;
			delete paramHandler;

		}


// ----------------------------------------------------------------- Run test window exponential [detection + time] ------------------------------------------------------------ //

	if (runTestWindowExp) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(EXPONENTIAL);
		paramHandler->setParLastProb(0.4);
		/***  ***/

		for (int seed=4; seed<5; seed++){
			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, false);
			queue<PubPkt*> tempPubQueue;
			//queue<BackSubPkt*> tempSubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setParWindowDistribution(sigma);
				Producer *p = new Producer(paramHandler, false);
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
				}
				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(sigma, innerSubQueue));
			}

	/*		for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createBackSubPkt();
				tempSubQueue.push(pkt);
			}
	*/
		// **** DATABASE *** //

			string nameDB = "sToRex_Simple_WindowTestExp_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Simple_WindowTestExp_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);


			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/

				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner* runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
				cout << "ciaoEXIT!" << endl;
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setNumSlot(50);

			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;

				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			configHandler->setMemoryTableType(ALLOCATION);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}


		// **** CACHE *** //

			string nameCache = "sToRex_Simple_WindowTestExp_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Simple_WindowTestExp_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			//configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner =  new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

/*
		// **** DISK *** //

			string nameDisk = "sToRex_TableTestSlot_Disk";
			stringstream streamDisk;
			string detectionFileDisk;
			getDetectionFile(detectionFileDisk, nameDisk);

			string nameDisk2 = "sToRex_TableTestSlot_Disk";
			string timesFileDisk;
			getProcTimeFile(timesFileDisk, nameDisk2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(DISK);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}
*/

			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
				while (it->second.size() != 0){
					BackSubPkt* pkt = it->second.front();
					it->second.pop();
					delete pkt;
				}
			}

		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;

	}













// -----------------------------**------------------------------------ Run test window size [detection + time] -----------------------------**------------------------------- //

	if (runTestWindowSize) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);
		paramHandler->setParLastProb(0.4);
		paramHandler->setMaxWindowSize(2*1000);
		/***  ***/

		for (int seed=4; seed<5; seed++){
			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, false);
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setIncremento(size);
				Producer *p = new Producer(paramHandler, false);
				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(size, innerSubQueue));
			}
/*			srand(seed);
			paramHandler->setSeed(seed);
			paramHandler->setMaxWindowSize(500*1000);
			Producer *p2 = new Producer(paramHandler, false);
			queue<BackSubPkt*> innerSubQueue;
			for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p2->createBackSubPkt();
				innerSubQueue.push(pkt);
			}
			tempSubsMap.insert(make_pair(-1, innerSubQueue));
*/

		// **** DATABASE *** //

			string nameDB = "sToRex_Simple_WindowSizeTest_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Simple_WindowSizeTest_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/

				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setNumSlot(50);

			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setNumSlot(50);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;

				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(500);
			configHandler->setNumSlot(50);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}


		// **** CACHE *** //
/*
			string nameCache = "sToRex_WindowSizeTest_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_WindowSizeTest_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(CACHE);
			//configHandler->setIndexingType(SIMPLE);
			//configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(0);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(-1)->second;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(0);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(0);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(0);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
			}
*/
/*
		// **** DISK *** //

			string nameDisk = "sToRex_TableTestSlot_Disk";
			stringstream streamDisk;
			string detectionFileDisk;
			getDetectionFile(detectionFileDisk, nameDisk);

			string nameDisk2 = "sToRex_TableTestSlot_Disk";
			string timesFileDisk;
			getProcTimeFile(timesFileDisk, nameDisk2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(DISK);
			for (int i=10; i<=10; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);pachetti
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}
*/
/*
			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
				while (it->second.size() != 0){
					BackSubPkt* pkt = it->second.front();
					it->second.pop();
					delete pkt;
				}
			}
*/
		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;

	}

	// ------------- Run test type  [detection + time] --------------- //

		if (runTestType) {
			ParamHandler *paramHandler = new ParamHandler();
			ConfigHandler *configHandler = new ConfigHandler();
			OutputListener *outputListener = new EvalOutputListener();

			/*** parametri del test ***/
			//paramHandler->setNumEventTypes(10);
			paramHandler->setNumNames(1000);
			paramHandler->setNumStringValues(200);
			paramHandler->setMaxNumAttributes(4);
			paramHandler->setMinNumAttributes(1);
			paramHandler->setMaxIntValue(1000);
			paramHandler->setMinIntValue(5);
			paramHandler->setPubNum (10000);
			paramHandler->setSubNum(400);
			paramHandler->setNumInterfaces(8);
			paramHandler->setMaxWindowSize(300*1000); // Milliseconds
			paramHandler->setPercIntEq(20);
			paramHandler->setPercIntGt(40);
			paramHandler->setPercIntLt(40);
			paramHandler->setEventInputDistribution(NORMAL);
			paramHandler->setSubsInputDistribution(NORMAL);
			paramHandler->setWindowSizeDistribution(NORMAL);
			paramHandler->setParWindowDistribution(1);
			paramHandler->setParLastProb(0.4);
			/***  ***/

			for (int seed=0; seed<1; seed++){

			// **** DATABASE *** //

				string nameDB = "sToRex_Simple_TableTestType_Database";
				stringstream streamDB;
				string detectionFileDB;
				getDetectionFile(detectionFileDB, nameDB);

				string nameDB2 = "sToRex_Simple_TableTestType_Database";
				string timesFileDB;
				getProcTimeFile(timesFileDB, nameDB2);
/*
				//Oracolo
				configHandler->setDefaultOracle();
				for (int i=10; i<=100; i=i+20){
					srand(seed);
					paramHandler->setSeed(seed);
					paramHandler->setNumEventTypes(i);
					Producer *p = new Producer(paramHandler, false);
					queue<PubPkt*> tempPubQueue;
					queue<BackSubPkt*> tempSubQueue;
					for (int i=0; i<paramHandler->getPubNum(); i++) {
						PubPkt *pkt = p->createPubPkt();
						tempPubQueue.push(pkt);
					}
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						tempSubQueue.push(pkt);
					}
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));

				}
*/
				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setNumSlot(50);
				for (int i=10; i<=100; i=i+20){
					srand(seed);
					paramHandler->setSeed(seed);
					paramHandler->setNumEventTypes(i);
					Producer *p = new Producer(paramHandler, false);
					queue<PubPkt*> tempPubQueue;
					queue<BackSubPkt*> tempSubQueue;
					for (int i=0; i<paramHandler->getPubNum(); i++) {
						PubPkt *pkt = p->createPubPkt();
						tempPubQueue.push(pkt);
					}
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						tempSubQueue.push(pkt);
					}
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setNumSlot(50);
				for (int i=10; i<=100; i=i+20){
					srand(seed);
					paramHandler->setSeed(seed);
					paramHandler->setNumEventTypes(i);
					Producer *p = new Producer(paramHandler, false);
					queue<PubPkt*> tempPubQueue;
					queue<BackSubPkt*> tempSubQueue;
					for (int i=0; i<paramHandler->getPubNum(); i++) {
						PubPkt *pkt = p->createPubPkt();
						tempPubQueue.push(pkt);
					}
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						tempSubQueue.push(pkt);
					}
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(50);
				for (int i=10; i<=100; i=i+20){
					srand(seed);
					paramHandler->setSeed(seed);
					paramHandler->setNumEventTypes(i);
					Producer *p = new Producer(paramHandler, false);
					queue<PubPkt*> tempPubQueue;
					queue<BackSubPkt*> tempSubQueue;
					for (int i=0; i<paramHandler->getPubNum(); i++) {
						PubPkt *pkt = p->createPubPkt();
						tempPubQueue.push(pkt);
					}
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						tempSubQueue.push(pkt);
					}
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
				}


				//allocationTable
				configHandler->setDefaultSienaFF();
				configHandler->setMemoryTableType(ALLOCATION);
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(50);
				for (int i=10; i<=100; i=i+20){
					srand(seed);
					paramHandler->setSeed(seed);
					paramHandler->setNumEventTypes(i);
					Producer *p = new Producer(paramHandler, false);
					queue<PubPkt*> tempPubQueue;
					queue<BackSubPkt*> tempSubQueue;
					for (int i=0; i<paramHandler->getPubNum(); i++) {
						PubPkt *pkt = p->createPubPkt();
						tempPubQueue.push(pkt);
					}
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						tempSubQueue.push(pkt);
					}
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "AllocationTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));

				}


			// **** CACHE *** //
/*
				string nameCache = "sToRex_Simple_TableTestSlot_Cache";
				stringstream streamCache;
				string detectionFileCache;
				getDetectionFile(detectionFileCache, nameCache);

				string nameCache2 = "sToRex_Simple_TableTestSlot_Cache";
				string timesFileCache;
				getProcTimeFile(timesFileCache, nameCache2);
	/*
				//Oracolo
				configHandler->setDefaultOracle();
				//configHandler->setStorageType(CACHE);
				//configHandler->setIndexingType(SIMPLE);
				for (int i=10; i<=10; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));

				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setSubsThreshold(150);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
				}
	*/
				//allocationTable
/*				configHandler->setDefaultSienaFF();
				configHandler->setMemoryTableType(ALLOCATION);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setSubsThreshold(150);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "AllocationTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
				}

	/*
			// **** DISK *** //

				string nameDisk = "sToRex_TableTestSlot_Disk";
				stringstream streamDisk;
				string detectionFileDisk;
				getDetectionFile(detectionFileDisk, nameDisk);

				string nameDisk2 = "sToRex_TableTestSlot_Disk";
				string timesFileDisk;
				getProcTimeFile(timesFileDisk, nameDisk2);

				//Oracolo
				configHandler->setDefaultOracle();
				//configHandler->setStorageType(DISK);
				for (int i=10; i<=10; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setStorageType(DISK);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setStorageType(DISK);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setStorageType(DISK);
				configHandler->setSubsThreshold(150);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}
	*/
/*
				while (tempPubQueue.size() != 0){
					PubPkt* pkt = tempPubQueue.front();
					tempPubQueue.pop();
					delete pkt;
				}

				while (tempSubQueue.size() != 0){
					BackSubPkt* pkt = tempSubQueue.front();
					tempSubQueue.pop();
					delete pkt;
				}
*/
			}

			delete outputListener;
			delete configHandler;
			delete paramHandler;

		}



		// ------------- Run table test extended (per slot) [detection + time] --------------- //

			if (runTestSlotExtended) {
				ParamHandler *paramHandler = new ParamHandler();
				ConfigHandler *configHandler = new ConfigHandler();
				OutputListener *outputListener = new EvalOutputListener();

				/*** parametri del test ***/
				paramHandler->setNumEventTypes(10);
				paramHandler->setNumNames(1000);
				paramHandler->setNumStringValues(200);
				paramHandler->setMaxNumAttributes(4);
				paramHandler->setMinNumAttributes(1);
				paramHandler->setMaxIntValue(1000);
				paramHandler->setMinIntValue(5);
				paramHandler->setPubNum (10000);
				paramHandler->setSubNum(400);
				paramHandler->setNumInterfaces(8);
				paramHandler->setMaxWindowSize(300*1000); // Milliseconds
				paramHandler->setPercIntEq(20);
				paramHandler->setPercIntGt(40);
				paramHandler->setPercIntLt(40);
				paramHandler->setEventInputDistribution(NORMAL);
				paramHandler->setSubsInputDistribution(NORMAL);
				paramHandler->setWindowSizeDistribution(NORMAL);
				paramHandler->setParWindowDistribution(1);
				paramHandler->setParLastProb(0.4);
				/***  ***/

				for (int seed=4; seed<5; seed++){

					paramHandler->setSeed(seed);
					Producer *p = new Producer(paramHandler, false);
					queue<PubPkt*> tempPubQueue;
					queue<BackSubPkt*> tempSubQueue;
					for (int i=0; i<paramHandler->getPubNum(); i++) {
						PubPkt *pkt = p->createPubPkt();
						tempPubQueue.push(pkt);
					}
					for (int i=0; i<paramHandler->getSubNum(); i++) {
						BackSubPkt *pkt = p->createBackSubPkt();
						tempSubQueue.push(pkt);
					}

				// **** DATABASE *** //

					string nameDB = "sToRex_Simple_TestSlotExtended_Database";
					stringstream streamDB;
					string detectionFileDB;
					getDetectionFile(detectionFileDB, nameDB);

					string nameDB2 = "sToRex_Simple_TestSlotExtended_Database";
					string timesFileDB;
					getProcTimeFile(timesFileDB, nameDB2);

					//Oracolo
					configHandler->setDefaultOracle();
					configHandler->setStorageType(DATABASE);
					for (int i=10; i<=10; i=i+50){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						//configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "Oracolo";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));

					}

					//FIFOTable
					configHandler->setDefaultOCM();
					configHandler->setMemoryTableType(FIFO);
					for (int i=300; i<=400; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner->startEval(pktQueue);
						string label = "FIFOTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDB.data() , (i==300), (i==300));
						outputListener->printMeanProcTime(label, timesFileDB.data() , (i==300), (i==300));
					}


					//eventTable
					configHandler->setDefaultOCM();
					for (int i=300; i<=400; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner->startEval(pktQueue);
						string label = "EventTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDB.data() , (i==300), (i==300));
						outputListener->printMeanProcTime(label, timesFileDB.data() , (i==300), (i==300));
					}


					//priorityTable
					configHandler->setDefaultSienaFF();
					configHandler->setSubsThreshold(150);
					for (int i=300; i<=400; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "PriorityTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDB.data() , (i==300), (i==300));
						outputListener->printMeanProcTime(label, timesFileDB.data() , (i==300), (i==300));
					}


					//allocationTable
					configHandler->setDefaultSienaFF();
					configHandler->setMemoryTableType(ALLOCATION);
					configHandler->setSubsThreshold(500);
					for (int i=300; i<=400; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner->startEval(pktQueue);
						string label = "AllocationTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDB.data() , (i==300), (i==300));
						outputListener->printMeanProcTime(label, timesFileDB.data() , (i==300), (i==300));

					}


				// **** CACHE *** //

					string nameCache = "sToRex_Simple_TestSlotExtended_Cache";
					stringstream streamCache;
					string detectionFileCache;
					getDetectionFile(detectionFileCache, nameCache);

					string nameCache2 = "sToRex_Simple_TestSlotExtended_Cache";
					string timesFileCache;
					getProcTimeFile(timesFileCache, nameCache2);
		/*
					//Oracolo
					configHandler->setDefaultOracle();
					//configHandler->setStorageType(CACHE);
					//configHandler->setIndexingType(SIMPLE);
					for (int i=10; i<=10; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						//configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "Oracolo";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));

					}

					//FIFOTable
					configHandler->setDefaultOCM();
					configHandler->setMemoryTableType(FIFO);
					configHandler->setStorageType(CACHE);
					configHandler->setIndexingType(SIMPLE);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "FIFOTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
					}

					//eventTable
					configHandler->setDefaultOCM();
					configHandler->setStorageType(CACHE);
					configHandler->setIndexingType(SIMPLE);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "EventTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
					}

					//priorityTable
					configHandler->setDefaultSienaFF();
					configHandler->setStorageType(CACHE);
					configHandler->setIndexingType(SIMPLE);
					configHandler->setSubsThreshold(150);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "PriorityTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
					}

					//allocationTable
					configHandler->setDefaultSienaFF();
					configHandler->setMemoryTableType(ALLOCATION);
					configHandler->setStorageType(CACHE);
					configHandler->setIndexingType(SIMPLE);
					configHandler->setSubsThreshold(150);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "AllocationTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
					}

	*/	/*
				// **** DISK *** //

					string nameDisk = "sToRex_TableTestSlot_Disk";
					stringstream streamDisk;
					string detectionFileDisk;
					getDetectionFile(detectionFileDisk, nameDisk);

					string nameDisk2 = "sToRex_TableTestSlot_Disk";
					string timesFileDisk;
					getProcTimeFile(timesFileDisk, nameDisk2);

					//Oracolo
					configHandler->setDefaultOracle();
					//configHandler->setStorageType(DISK);
					for (int i=10; i<=10; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						//configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "Oracolo";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

					}

					//FIFOTable
					configHandler->setDefaultOCM();
					configHandler->setMemoryTableType(FIFO);
					configHandler->setStorageType(DISK);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "FIFOTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
					}

					//eventTable
					configHandler->setDefaultOCM();
					configHandler->setStorageType(DISK);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "EventTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
					}

					//priorityTable
					configHandler->setDefaultSienaFF();
					configHandler->setStorageType(DISK);
					configHandler->setSubsThreshold(150);
					for (int i=10; i<=100; i=i+10){
						srand(seed);
						queue<PktPtr> pktQueue;
						queue<PubPkt*> pubQueue = tempPubQueue;
						queue<BackSubPkt*> subQueue = tempSubQueue;
						int pubsLeft = paramHandler->getPubNum();
						int subsLeft = paramHandler->getSubNum();
						for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
							if(rand()%2==0){
								if (pubsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;
								}
							} else {
								if (subsLeft != 0){
									PktPtr* pkt= new PktPtr();
									*pkt = subQueue.front()->copy();
									subQueue.pop();
									pktQueue.push(*pkt);
									subsLeft--;

								} else {
									PktPtr* pkt= new PktPtr();
									*pkt = pubQueue.front()->copy();
									pubQueue.pop();
									pktQueue.push(*pkt);
									pubsLeft--;
								}
							}
						}
						configHandler->setNumSlot(i);
						EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
						outputListener->reset();
						runner.startEval(pktQueue);
						string label = "PriorityTable";
						label += util::intToString(seed);
						outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
						outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
					}
		*/

					while (tempPubQueue.size() != 0){
						PubPkt* pkt = tempPubQueue.front();
						tempPubQueue.pop();
						delete pkt;
					}

					while (tempSubQueue.size() != 0){
						BackSubPkt* pkt = tempSubQueue.front();
						tempSubQueue.pop();
						delete pkt;
					}

				}

				delete outputListener;
				delete configHandler;
				delete paramHandler;

			}









}


// *************************************************************************************************************************************************************************** //
// ************************************************************************** COMPLEX **************************************************************************************** //
// *************************************************************************************************************************************************************************** //

if (complex){

	if (runTableTestSlot) {

		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();


		// *** parametri del test *** //
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);
		paramHandler->setParLastProb(0.4);

		paramHandler->setNumRules(10);
		paramHandler->setNumRulePredicates(2);
		paramHandler->setNumRuleNegations(0);
		paramHandler->setNumRuleParameters(0);
		paramHandler->setMinWinSize(1*1000);
		paramHandler->setMaxWinSize(3*1000);
		paramHandler->setEachPerc(0); //60
		paramHandler->setFirstPerc(0);	//20
		paramHandler->setLastPerc(100);	//20
		paramHandler->setUseConsuming(false);
		// *** *** //

		for (int seed=14; seed<15; seed++){

			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, true);

			// creazione eventi
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			//creazione regole
			set<RulePkt*> rulePkts;
			p->createRulePkts(rulePkts);

			// creazione sottoscrizioni
			queue<BackSubPkt*> tempSubQueue;
			for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createComplexBackSubPkt();
				tempSubQueue.push(pkt);
			}

		// **** DATABASE *** //

			string nameDB = "sToRex_Complex_TableTestSlot_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Complex_TableTestSlot_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);
			for (int i=10; i<=10; i=i+10){
				srand(seed);

				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}


		// **** CACHE *** //
/*
			string nameCache = "sToRex_Complex_TableTestSlot_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Complex_TableTestSlot_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(CACHE);
			//configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}
*/
		}
		delete outputListener;
		delete configHandler;
		delete paramHandler;
	}


// ----------------------------------------------------------------- Run test window [detection + time] ------------------------------------------------------------ //


if (runTestWindow) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParLastProb(0.4);

		paramHandler->setNumRules(10);
		paramHandler->setNumRulePredicates(2);
		paramHandler->setNumRuleNegations(0);
		paramHandler->setNumRuleParameters(0);
		paramHandler->setMinWinSize(1*1000);
		paramHandler->setMaxWinSize(3*1000);
		paramHandler->setEachPerc(60);
		paramHandler->setFirstPerc(20);
		paramHandler->setLastPerc(20);
		paramHandler->setUseConsuming(false);
		/***  ***/

		for (int seed=13; seed<14; seed++){

			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, true);

			// creazione eventi
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			//creazione regole
			set<RulePkt*> rulePkts;
			p->createRulePkts(rulePkts);

			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setParWindowDistribution(sigma);
				Producer *p = new Producer(paramHandler, true);
				// creazione eventi
				queue<PubPkt*> tempPubQueue;
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
					tempPubQueue.push(pkt);
				}
				//creazione regole
				set<RulePkt*> rulePkts;
				p->createRulePkts(rulePkts);
				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createComplexBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(sigma, innerSubQueue));
			}



		// **** DATABASE *** //

			string nameDB = "sToRex_Complex_WindowTest_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Complex_WindowTest_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);

			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setNumSlot(50);

			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;

				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}

*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}


			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}

*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

		// **** CACHE *** //

			string nameCache = "sToRex_Complex_WindowTest_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Complex_WindowTest_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			//configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float sigma=32; sigma>=0.25; sigma=sigma*0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(sigma)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (sigma==32), (sigma==32));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (sigma==32), (sigma==32));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
				while (it->second.size() != 0){
					BackSubPkt* pkt = it->second.front();
					it->second.pop();
					delete pkt;
				}
			}

		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;

	}



// ----------------------------------------------------------------- Run test Last [detection + time] ------------------------------------------------------------ //

	if (runTestLast) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);

		paramHandler->setNumRules(10);
		paramHandler->setNumRulePredicates(2);
		paramHandler->setNumRuleNegations(0);
		paramHandler->setNumRuleParameters(0);
		paramHandler->setMinWinSize(1*1000);
		paramHandler->setMaxWinSize(3*1000);
		paramHandler->setEachPerc(60);
		paramHandler->setFirstPerc(20);
		paramHandler->setLastPerc(20);
		paramHandler->setUseConsuming(false);
		/***  ***/

		for (int seed=14; seed<15; seed++){

			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, true);

			// creazione eventi
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			//creazione regole
			set<RulePkt*> rulePkts;
			p->createRulePkts(rulePkts);

			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setParLastProb(probLast);
				Producer *p = new Producer(paramHandler, true);
				// creazione eventi
				queue<PubPkt*> tempPubQueue;
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
					tempPubQueue.push(pkt);
				}
				//creazione regole
				set<RulePkt*> rulePkts;
				p->createRulePkts(rulePkts);

				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createComplexBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(probLast, innerSubQueue));
			}

		// **** DATABASE *** //

			string nameDB = "sToRex_Complex_LastTest_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Complex_LastTest_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);

			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setNumSlot(50);

			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;

				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;

/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}


		// **** CACHE *** //

			string nameCache = "sToRex_Complex_LastTest_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Complex_LastTest_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			//configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*
				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float probLast=0; probLast<=1; probLast=probLast+0.1){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
/*				for (int i=0; i<paramHandler->getSubNum(); i++) {
					BackSubPkt *pkt = p->createBackSubPkt();
					subQueue.push(pkt);
				}
*/				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
/*
				while (subQueue.size() != 0){
					BackSubPkt* pkt = subQueue.front();
					subQueue.pop();
					delete pkt;
				}
*/			}

/*
		// **** DISK *** //

			string nameDisk = "sToRex_TableTestSlot_Disk";
			stringstream streamDisk;
			string detectionFileDisk;
			getDetectionFile(detectionFileDisk, nameDisk);

			string nameDisk2 = "sToRex_TableTestSlot_Disk";
			string timesFileDisk;
			getProcTimeFile(timesFileDisk, nameDisk2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(DISK);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}
*/

			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
				while (it->second.size() != 0){
					BackSubPkt* pkt = it->second.front();
					it->second.pop();
					delete pkt;
				}
			}

		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;

	}



// -----------------------------**------------------------------------ Run test window size [detection + time] -----------------------------**------------------------------- //

	if (runTestWindowSize) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		/*** parametri del test ***/
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);
		paramHandler->setParLastProb(0.4);
		paramHandler->setMaxWindowSize(2*1000);

		paramHandler->setNumRules(10);
		paramHandler->setNumRulePredicates(2);
		paramHandler->setNumRuleNegations(0);
		paramHandler->setNumRuleParameters(0);
		paramHandler->setMinWinSize(1*1000);
		paramHandler->setMaxWinSize(3*1000);
		paramHandler->setEachPerc(60);
		paramHandler->setFirstPerc(20);
		paramHandler->setLastPerc(20);
		paramHandler->setUseConsuming(false);
		/***  ***/

		for (int seed=12; seed<13; seed++){

			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, true);

			// creazione eventi
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			//creazione regole
			set<RulePkt*> rulePkts;
			p->createRulePkts(rulePkts);

			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setIncremento(size);
				Producer *p = new Producer(paramHandler, true);
				// creazione eventi
				queue<PubPkt*> tempPubQueue;
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
					tempPubQueue.push(pkt);
				}
				//creazione regole
				set<RulePkt*> rulePkts;
				p->createRulePkts(rulePkts);

				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createComplexBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(size, innerSubQueue));
			}

		// **** DATABASE *** //

			string nameDB = "sToRex_Complex_WindowSizeTest_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Complex_WindowSizeTest_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);

			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setNumSlot(50);

			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setNumSlot(50);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;

				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(500);
			configHandler->setNumSlot(50);
			for (float size=1; size<=4; size=size+0.5){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (size==1), (size==1));
			}


		// **** CACHE *** //
/*
			string nameCache = "sToRex_Complex_WindowSizeTest_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Complex_WindowSizeTest_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(CACHE);
			//configHandler->setIndexingType(SIMPLE);
			//configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(-1)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));
		}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			configHandler->setNumSlot(50);
			for (int size=1; size<=101; size=size+20){
				srand(seed);
//				paramHandler->setSeed(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(size)->second;

				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}

				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (size==1), (size==1));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (size==1), (size==1));
			}
*/
/*
		// **** DISK *** //

			string nameDisk = "sToRex_TableTestSlot_Disk";
			stringstream streamDisk;
			string detectionFileDisk;
			getDetectionFile(detectionFileDisk, nameDisk);

			string nameDisk2 = "sToRex_TableTestSlot_Disk";
			string timesFileDisk;
			getProcTimeFile(timesFileDisk, nameDisk2);

			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(DISK);
			for (int i=10; i<=10; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(DISK);
			for (int i=10; i<=100; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(DISK);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);pachetti
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
			}
*/
/*
			while (tempPubQueue.size() != 0){
				PubPkt* pkt = tempPubQueue.front();
				tempPubQueue.pop();
				delete pkt;
			}

			for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
				while (it->second.size() != 0){
					BackSubPkt* pkt = it->second.front();
					it->second.pop();
					delete pkt;
				}
			}
*/
		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;
	}

// ------------------------------------------- Test slot extreme ----------------------------------------- //

	if (runTestSlotExtended) {

		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();


		// *** parametri del test *** //
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);
		paramHandler->setParLastProb(0.4);

		paramHandler->setNumRules(10);
		paramHandler->setNumRulePredicates(2);
		paramHandler->setNumRuleNegations(0);
		paramHandler->setNumRuleParameters(0);
		paramHandler->setMinWinSize(1*1000);
		paramHandler->setMaxWinSize(3*1000);
		paramHandler->setEachPerc(60);
		paramHandler->setFirstPerc(20);
		paramHandler->setLastPerc(20);
		paramHandler->setUseConsuming(false);
		// *** *** //

		for (int seed=14; seed<15; seed++){

			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, true);

			// creazione eventi
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			//creazione regole
			set<RulePkt*> rulePkts;
			p->createRulePkts(rulePkts);

			// creazione sottoscrizioni
			queue<BackSubPkt*> tempSubQueue;
			for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createComplexBackSubPkt();
				tempSubQueue.push(pkt);
			}

		// **** DATABASE *** //

			string nameDB = "sToRex_Complex_TestSlotExtended_Database";
			stringstream streamDB;
			string detectionFileDB;
			getDetectionFile(detectionFileDB, nameDB);

			string nameDB2 = "sToRex_Complex_TestSlotExtended_Database";
			string timesFileDB;
			getProcTimeFile(timesFileDB, nameDB2);

			//Oracolo
			configHandler->setDefaultOracle();
			configHandler->setStorageType(DATABASE);
			for (int i=10; i<=10; i=i+10){
				srand(seed);

				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==10), (i==10));
			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			for (int i=100; i<=500; i=i+50){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==100), (i==100));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==100), (i==100));
			}

			//eventTable
			configHandler->setDefaultOCM();
			for (int i=100; i<=500; i=i+50){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==100), (i==100));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==100), (i==100));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setSubsThreshold(150);
			for (int i=100; i<=500; i=i+50){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==100), (i==100));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==100), (i==100));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setSubsThreshold(500);
			for (int i=100; i<=500; i=i+50){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner->startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileDB.data() , (i==100), (i==100));
				outputListener->printMeanProcTime(label, timesFileDB.data() , (i==100), (i==100));
			}


		// **** CACHE *** //

			string nameCache = "sToRex_Complex_TableTestSlot_Cache";
			stringstream streamCache;
			string detectionFileCache;
			getDetectionFile(detectionFileCache, nameCache);

			string nameCache2 = "sToRex_Complex_TableTestSlot_Cache";
			string timesFileCache;
			getProcTimeFile(timesFileCache, nameCache2);
/*
			//Oracolo
			configHandler->setDefaultOracle();
			//configHandler->setStorageType(CACHE);
			//configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=10; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "Oracolo";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));

			}

			//FIFOTable
			configHandler->setDefaultOCM();
			configHandler->setMemoryTableType(FIFO);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "FIFOTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//eventTable
			configHandler->setDefaultOCM();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "EventTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//priorityTable
			configHandler->setDefaultSienaFF();
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "PriorityTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}

			//allocationTable
			configHandler->setDefaultSienaFF();
			configHandler->setMemoryTableType(ALLOCATION);
			configHandler->setStorageType(CACHE);
			configHandler->setIndexingType(SIMPLE);
			configHandler->setSubsThreshold(150);
			for (int i=10; i<=100; i=i+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
					PktPtr* pkt= new PktPtr();
					*pkt = *it;
					pktQueue.push(*pkt);
				}
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				string label = "AllocationTable";
				label += util::intToString(seed);
				outputListener->printToFile(label, detectionFileCache.data() , (i==10), (i==10));
				outputListener->printMeanProcTime(label, timesFileCache.data() , (i==10), (i==10));
			}
*/
		}
		delete outputListener;
		delete configHandler;
		delete paramHandler;
	}


// ------------------------------------------------ each-last rules test ---------------------------------------------------- //

	if (runEachLastRuleTest) {

		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();


		// *** parametri del test *** //
		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);
		paramHandler->setParWindowDistribution(1);
		paramHandler->setParLastProb(0.4);

		paramHandler->setNumRules(10);
		paramHandler->setNumRulePredicates(2);
		paramHandler->setNumRuleNegations(0);
		paramHandler->setNumRuleParameters(0);
		paramHandler->setMinWinSize(1*1000);
		paramHandler->setMaxWinSize(3*1000);
	//	paramHandler->setEachPerc(100); //60
		paramHandler->setFirstPerc(0);	//20
	//	paramHandler->setLastPerc(0);	//20
		paramHandler->setUseConsuming(false);
		// *** *** //

		for (int seed=0; seed<1; seed++){

			srand(seed);
			paramHandler->setSeed(seed);
			Producer *p = new Producer(paramHandler, true);

			// creazione eventi
			queue<PubPkt*> tempPubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}

			map<float, set<RulePkt*> > tempRulesMap;
			map<float, queue<BackSubPkt*> > tempSubsMap;
			for (float probLast=0; probLast<=100; probLast=probLast+10){
				srand(seed);
				paramHandler->setSeed(seed);
				paramHandler->setEachPerc(100-probLast);
				paramHandler->setLastPerc(probLast);
				Producer *p = new Producer(paramHandler, true);

				// creazione eventi
				queue<PubPkt*> tempPubQueue;
				for (int i=0; i<paramHandler->getPubNum(); i++) {
					PubPkt *pkt = p->createPubPkt();
					tempPubQueue.push(pkt);
				}

				//creazione regole
				set<RulePkt*> tempRulePkts;
				p->createRulePkts(tempRulePkts);
				tempRulesMap.insert(make_pair(probLast, tempRulePkts));

				queue<BackSubPkt*> innerSubQueue;
				for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createComplexBackSubPkt();
					innerSubQueue.push(pkt);
				}
				tempSubsMap.insert(make_pair(probLast, innerSubQueue));
			}


			// **** DATABASE *** //

				string nameDB = "sToRex_Complex_EachLastRuleTest_Database";
				stringstream streamDB;
				string detectionFileDB;
				getDetectionFile(detectionFileDB, nameDB);

				string nameDB2 = "sToRex_Complex_EachLastRuleTest_Database";
				string timesFileDB;
				getProcTimeFile(timesFileDB, nameDB2);

				//Oracolo
				configHandler->setDefaultOracle();
				configHandler->setStorageType(DATABASE);

				for (float probLast=0; probLast<=100; probLast=probLast+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					set<RulePkt*> rulePkts = tempRulesMap.find(probLast)->second;


					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));

				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setNumSlot(50);

				for (float probLast=0; probLast<=100; probLast=probLast+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					set<RulePkt*> rulePkts = tempRulesMap.find(probLast)->second;

					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=100; probLast=probLast+10){
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
				set<RulePkt*> rulePkts = tempRulesMap.find(probLast)->second;

					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(50);

				for (float probLast=0; probLast<=100; probLast=probLast+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					set<RulePkt*> rulePkts = tempRulesMap.find(probLast)->second;

					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
				}

				//allocationTable
				configHandler->setDefaultSienaFF();
				configHandler->setMemoryTableType(ALLOCATION);
				configHandler->setSubsThreshold(500);
				configHandler->setNumSlot(50);

				for (float probLast=0; probLast<=100; probLast=probLast+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					set<RulePkt*> rulePkts = tempRulesMap.find(probLast)->second;

					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "AllocationTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDB.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileDB.data() , (probLast==0), (probLast==0));
				}


			// **** CACHE *** //
/*
				string nameCache = "sToRex_Complex_LastTest_Cache";
				stringstream streamCache;
				string detectionFileCache;
				getDetectionFile(detectionFileCache, nameCache);

				string nameCache2 = "sToRex_Complex_LastTest_Cache";
				string timesFileCache;
				getProcTimeFile(timesFileCache, nameCache2);

				//Oracolo
				configHandler->setDefaultOracle();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				//configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));

				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner *runner = new EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner->startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
				}

				//allocationTable
				configHandler->setDefaultSienaFF();
				configHandler->setMemoryTableType(ALLOCATION);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				configHandler->setSubsThreshold(150);
				configHandler->setNumSlot(50);
				for (float probLast=0; probLast<=1; probLast=probLast+0.1){
					srand(seed);
	//				paramHandler->setSeed(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubsMap.find(probLast)->second;
					for (set<RulePkt*>::iterator it = rulePkts.begin(); it != rulePkts.end(); it++){
						PktPtr* pkt= new PktPtr();
						*pkt = *it;
						pktQueue.push(*pkt);
					}
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}

					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "AllocationTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileCache.data() , (probLast==0), (probLast==0));
					outputListener->printMeanProcTime(label, timesFileCache.data() , (probLast==0), (probLast==0));
				}

	/*
			// **** DISK *** //

				string nameDisk = "sToRex_TableTestSlot_Disk";
				stringstream streamDisk;
				string detectionFileDisk;
				getDetectionFile(detectionFileDisk, nameDisk);

				string nameDisk2 = "sToRex_TableTestSlot_Disk";
				string timesFileDisk;
				getProcTimeFile(timesFileDisk, nameDisk2);

				//Oracolo
				configHandler->setDefaultOracle();
				//configHandler->setStorageType(DISK);
				for (int i=10; i<=10; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					//configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "Oracolo";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));

				}

				//FIFOTable
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(FIFO);
				configHandler->setStorageType(DISK);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "FIFOTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}

				//eventTable
				configHandler->setDefaultOCM();
				configHandler->setStorageType(DISK);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "EventTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}

				//priorityTable
				configHandler->setDefaultSienaFF();
				configHandler->setStorageType(DISK);
				configHandler->setSubsThreshold(150);
				for (int i=10; i<=100; i=i+10){
					srand(seed);
					queue<PktPtr> pktQueue;
					queue<PubPkt*> pubQueue = tempPubQueue;
					queue<BackSubPkt*> subQueue = tempSubQueue;
					int pubsLeft = paramHandler->getPubNum();
					int subsLeft = paramHandler->getSubNum();
					for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
						if(rand()%2==0){
							if (pubsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;
							}
						} else {
							if (subsLeft != 0){
								PktPtr* pkt= new PktPtr();
								*pkt = subQueue.front()->copy();
								subQueue.pop();
								pktQueue.push(*pkt);
								subsLeft--;

							} else {
								PktPtr* pkt= new PktPtr();
								*pkt = pubQueue.front()->copy();
								pubQueue.pop();
								pktQueue.push(*pkt);
								pubsLeft--;
							}
						}
					}
					configHandler->setNumSlot(i);
					EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
					outputListener->reset();
					runner.startEval(pktQueue);
					string label = "PriorityTable";
					label += util::intToString(seed);
					outputListener->printToFile(label, detectionFileDisk.data() , (i==10), (i==10));
					outputListener->printMeanProcTime(label, timesFileDisk.data() , (i==10), (i==10));
				}
	*/
/*
				while (tempPubQueue.size() != 0){
					PubPkt* pkt = tempPubQueue.front();
					tempPubQueue.pop();
					delete pkt;
				}

				for (map<float, queue<BackSubPkt*> >::iterator it = tempSubsMap.begin(); it != tempSubsMap.end(); it++){
					while (it->second.size() != 0){
						BackSubPkt* pkt = it->second.front();
						it->second.pop();
						delete pkt;
					}
				}
*/
			}

			delete outputListener;
			delete configHandler;
			delete paramHandler;

		}





















/*




// -------------- Run priority table test (per threshold) [detection + time] --------------- //

	if (runPriorityTableTestThresold) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();


		paramHandler->setNumEventTypes(10);
		paramHandler->setNumNames(1000);
		paramHandler->setNumStringValues(200);
		paramHandler->setMaxNumAttributes(4);
		paramHandler->setMinNumAttributes(1);
		paramHandler->setMaxIntValue(1000);
		paramHandler->setMinIntValue(5);
		paramHandler->setPubNum (10000);
		paramHandler->setSubNum(400);
		paramHandler->setNumInterfaces(8);
		paramHandler->setMaxWindowSize(300*1000); // Milliseconds
		paramHandler->setPercIntEq(20);
		paramHandler->setPercIntGt(40);
		paramHandler->setPercIntLt(40);
		paramHandler->setEventInputDistribution(NORMAL);
		paramHandler->setSubsInputDistribution(NORMAL);
		paramHandler->setWindowSizeDistribution(NORMAL);


		Producer *p = new Producer(paramHandler);
		queue<PubPkt*> tempPubQueue;
		queue<BackSubPkt*> tempSubQueue;
		for (int i=0; i<paramHandler->getPubNum(); i++) {
			PubPkt *pkt = p->createPubPkt();
			tempPubQueue.push(pkt);
		}
		for (int i=0; i<paramHandler->getSubNum(); i++) {
			BackSubPkt *pkt = p->createBackSubPkt();
			tempSubQueue.push(pkt);
		}

		string name = "sToRex_PriorityTableTestThresold";
		stringstream stream;
		string detectionFile;
		getDetectionFile(detectionFile, name);

		string name2 = "sToRex_PriorityTableTestThresold";
		string timesFile;
		getProcTimeFile(timesFile, name2);

		configHandler->setDefaultSienaFF();

		//nessuno
		for (int i=10; i<=100; i=i+10){
			configHandler->setSubsThreshold(5000);
			srand(0);
			queue<PktPtr> pktQueue;
			queue<PubPkt*> pubQueue = tempPubQueue;
			queue<BackSubPkt*> subQueue = tempSubQueue;
			int pubsLeft = paramHandler->getPubNum();
			int subsLeft = paramHandler->getSubNum();
			for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
				if(rand()%2==0){
					if (pubsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;
					}
				} else {
					if (subsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;

					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					}
				}
			}
			configHandler->setNumSlot(i);
			EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
			outputListener->reset();
			runner.startEval(pktQueue);
			outputListener->printToFile("ThresholdInf", detectionFile.data() , (i==10), (i==10));
			outputListener->printMeanProcTime("ThresholdInf", timesFile.data() , (i==10), (i==10));
		}

		//soglia 300
		for (int i=10; i<=100; i=i+10){
			configHandler->setSubsThreshold(300);
			srand(0);
			queue<PktPtr> pktQueue;
			queue<PubPkt*> pubQueue = tempPubQueue;
			queue<BackSubPkt*> subQueue = tempSubQueue;
			int pubsLeft = paramHandler->getPubNum();
			int subsLeft = paramHandler->getSubNum();
			for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
				if(rand()%2==0){
					if (pubsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;
					}
				} else {
					if (subsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;

					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					}
				}
			}
			configHandler->setNumSlot(i);
			EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
			outputListener->reset();
			runner.startEval(pktQueue);
			outputListener->printToFile("Threshold300", detectionFile.data() , (i==10), (i==10));
			outputListener->printMeanProcTime("Threshold300", timesFile.data() , (i==10), (i==10));
		}

		//soglia 150
		for (int i=10; i<=100; i=i+10){
			configHandler->setSubsThreshold(150);
			srand(0);
			queue<PktPtr> pktQueue;
			queue<PubPkt*> pubQueue = tempPubQueue;
			queue<BackSubPkt*> subQueue = tempSubQueue;
			int pubsLeft = paramHandler->getPubNum();
			int subsLeft = paramHandler->getSubNum();
			for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
				if(rand()%2==0){
					if (pubsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;
					}
				} else {
					if (subsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;

					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					}
				}
			}
			configHandler->setNumSlot(i);
			EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
			outputListener->reset();
			runner.startEval(pktQueue);
			outputListener->printToFile("Threshold150", detectionFile.data() , (i==10), (i==10));
			outputListener->printMeanProcTime("Threshold150", timesFile.data() , (i==10), (i==10));
		}

		//soglia 100
		for (int i=10; i<=100; i=i+10){
			configHandler->setSubsThreshold(100);
			srand(0);
			queue<PktPtr> pktQueue;
			queue<PubPkt*> pubQueue = tempPubQueue;
			queue<BackSubPkt*> subQueue = tempSubQueue;
			int pubsLeft = paramHandler->getPubNum();
			int subsLeft = paramHandler->getSubNum();
			for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
				if(rand()%2==0){
					if (pubsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;
					}
				} else {
					if (subsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;

					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					}
				}
			}
			configHandler->setNumSlot(i);
			EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
			outputListener->reset();
			runner.startEval(pktQueue);
			outputListener->printToFile("Threshold100", detectionFile.data() , (i==10), (i==10));
			outputListener->printMeanProcTime("Threshold100", timesFile.data() , (i==10), (i==10));
		}

		//soglia 50
		for (int i=10; i<=100; i=i+10){
			configHandler->setSubsThreshold(50);
			srand(0);
			queue<PktPtr> pktQueue;
			queue<PubPkt*> pubQueue = tempPubQueue;
			queue<BackSubPkt*> subQueue = tempSubQueue;
			int pubsLeft = paramHandler->getPubNum();
			int subsLeft = paramHandler->getSubNum();
			for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
				if(rand()%2==0){
					if (pubsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;
					}
				} else {
					if (subsLeft != 0){
						PktPtr* pkt= new PktPtr();
						*pkt = subQueue.front()->copy();
						subQueue.pop();
						pktQueue.push(*pkt);
						subsLeft--;

					} else {
						PktPtr* pkt= new PktPtr();
						*pkt = pubQueue.front()->copy();
						pubQueue.pop();
						pktQueue.push(*pkt);
						pubsLeft--;
					}
				}
			}
			configHandler->setNumSlot(i);
			EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
			outputListener->reset();
			runner.startEval(pktQueue);
			outputListener->printToFile("Threshold50", detectionFile.data() , (i==10), (i==10));
			outputListener->printMeanProcTime("Threshold50", timesFile.data() , (i==10), (i==10));
		}

		delete outputListener;
		delete configHandler;
		delete paramHandler;
	}

// ------------- Run OCM storage test (per num events types) [time] --------------- //

	if (runStorageOCMTestNumTypes) {
		ParamHandler *paramHandler = new ParamHandler();
		ConfigHandler *configHandler = new ConfigHandler();
		OutputListener *outputListener = new EvalOutputListener();

		string name2 = "sToRex_StorageOCMTestNumTypes";
		string timesFile;
		getProcTimeFile(timesFile, name2);

		for (int j=100; j<=100; j=j+10){

			paramHandler->setNumEventTypes(j);

			paramHandler->setNumNames(10000);
			paramHandler->setNumStringValues(200);
			paramHandler->setMaxNumAttributes(4);
			paramHandler->setMinNumAttributes(1);
			paramHandler->setMaxIntValue(1000);
			paramHandler->setMinIntValue(5);
			paramHandler->setPubNum (10000);
			paramHandler->setSubNum(400);
			paramHandler->setNumInterfaces(8);
			paramHandler->setMaxWindowSize(300*1000); // Milliseconds
			paramHandler->setPercIntEq(20);
			paramHandler->setPercIntGt(40);
			paramHandler->setPercIntLt(40);
			paramHandler->setEventInputDistribution(NORMAL);
			paramHandler->setSubsInputDistribution(NORMAL);
			paramHandler->setWindowSizeDistribution(NORMAL);


			Producer *p = new Producer(paramHandler);
			queue<PubPkt*> tempPubQueue;
			queue<BackSubPkt*> tempSubQueue;
			for (int i=0; i<paramHandler->getPubNum(); i++) {
				PubPkt *pkt = p->createPubPkt();
				tempPubQueue.push(pkt);
			}
			for (int i=0; i<paramHandler->getSubNum(); i++) {
				BackSubPkt *pkt = p->createBackSubPkt();
				tempSubQueue.push(pkt);
			}


			//ORACOLO
			if (true) {
				configHandler->setDefaultOracle();
				srand(0);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				//configHandler->setNumSlot(i);
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				outputListener->printMeanProcTime("Oracolo", timesFile.data() , true, true);
			}

			//DATABASE
			if (true) {
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(EVENT);
				configHandler->setStorageType(DATABASE);
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				outputListener->printMeanProcTime("Database", timesFile.data() , false, true);
			}

			//CACHE
			if (true) {
				configHandler->setDefaultOCM();
				configHandler->setMemoryTableType(EVENT);
				configHandler->setStorageType(CACHE);
				configHandler->setIndexingType(SIMPLE);
				srand(seed);
				queue<PktPtr> pktQueue;
				queue<PubPkt*> pubQueue = tempPubQueue;
				queue<BackSubPkt*> subQueue = tempSubQueue;
				int pubsLeft = paramHandler->getPubNum();
				int subsLeft = paramHandler->getSubNum();
				for (int j=0; j<paramHandler->getPubNum()+paramHandler->getSubNum(); j++) {
					if(rand()%2==0){
						if (pubsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;
						}
					} else {
						if (subsLeft != 0){
							PktPtr* pkt= new PktPtr();
							*pkt = subQueue.front()->copy();
							subQueue.pop();
							pktQueue.push(*pkt);
							subsLeft--;

						} else {
							PktPtr* pkt= new PktPtr();
							*pkt = pubQueue.front()->copy();
							pubQueue.pop();
							pktQueue.push(*pkt);
							pubsLeft--;
						}
					}
				}
				EvaluationRunner runner = EvaluationRunner(configHandler, paramHandler, outputListener);
				outputListener->reset();
				runner.startEval(pktQueue);
				outputListener->printMeanProcTime("Cache", timesFile.data() , false, true);
			}

			delete outputListener;
			delete configHandler;
			delete paramHandler;
		}
	}*/

}

}
